#ifndef CWEBSOCKET_H
#define CWEBSOCKET_H

#include <QObject>
#include <QtWebSockets/QWebSocket> // 引入 WebSocket 模块
#include <QUrl>
#include <QString>
#include <QByteArray>
#include <QAbstractSocket> // 为了 QAbstractSocket::SocketError 和 SocketState

class CWebSocket : public QObject
{
    Q_OBJECT
public:
    explicit CWebSocket(QObject *parent = nullptr);

    ~CWebSocket() override;

    /**
     * @brief 连接到 WebSocket 服务器
     * @param url 服务器的 URL (例如 "ws://echo.websocket.org" 或 "wss://secure.example.com")
     */
    void connectToServer(const QUrl &url);

    /**
     * @brief 主动断开与服务器的连接
     */
    void disconnectFromServer();

    /**
     * @brief 检查当前是否已连接
     * @return 如果处于连接状态则返回 true，否则返回 false
     */
    bool isConnected() const;

    /**
     * @brief 获取当前的 WebSocket 连接状态
     * @return QAbstractSocket::SocketState 枚举值
     */
    QAbstractSocket::SocketState state() const;

    /**
     * @brief 发送二进制消息
     * @param data 要发送的字节数组
     * @return 发送的字节数，如果未连接或发送失败则可能为 -1 或 0
     */
    qint64 sendBinaryMessage(const QByteArray &data);

    /**
     * @brief 发送文本消息
     * @param message 要发送的字符串消息
     * @return 发送的字节数，如果未连接或发送失败则可能为 -1 或 0
     */
    qint64 sendTextMessage(const QString &message);

    /**
     * @brief 获取最后一次发生的错误信息
     * @return 描述错误的字符串
     */
    QString errorString() const;


signals:
    // --- 对外发出的信号 ---

    /**
     * @brief 当成功连接到服务器时发出此信号
     */
    void connected();

    /**
     * @brief 当与服务器的连接断开时发出此信号
     */
    void disconnected();

    /**
     * @brief 当收到服务器发送的文本消息时发出此信号
     * @param message 收到的文本消息内容
     */
    void textMessageReceived(const QString &message);

    /**
     * @brief 当收到服务器发送的二进制消息时发出此信号
     * @param message 收到的二进制数据
     */
    void binaryMessageReceived(const QByteArray &data);

    /**
     * @brief 当发生错误时发出此信号
     * @param errorString 错误的描述信息
     */
    void errorOccurred(const QString &errorString); // 使用 QString 传递更友好的错误信息

    /**
     * @brief 当连接状态改变时发出此信号
     * @param state 新的连接状态
     */
    void stateChanged(QAbstractSocket::SocketState state);


private slots:
    // --- 内部槽函数，用于处理 QWebSocket 的信号 ---

    /**
     * @brief 处理 QWebSocket 的 connected() 信号
     */
    void onConnected();

    /**
     * @brief 处理 QWebSocket 的 disconnected() 信号
     */
    void onDisconnected();

    /**
     * @brief 处理 QWebSocket 的 textMessageReceived(const QString &message) 信号
     */
    void onTextMessageReceived(const QString &message);

    /**
     * @brief 处理 QWebSocket 的 binaryMessageReceived(const QByteArray &message) 信号
     */
    void onBinaryMessageReceived(const QByteArray &data);

    /**
     * @brief 处理 QWebSocket 的 errorOccurred(QAbstractSocket::SocketError error) 信号
     * @param error 发生的套接字错误类型
     */
    void onErrorOccurred(QAbstractSocket::SocketError error);

    /**
     * @brief 处理 QWebSocket 的 sslErrors(const QList<QSslError> &errors) 信号 (用于 wss 连接)
     * @param errors SSL 错误列表
     */
    void onSslErrors(const QList<QSslError> &errors);

    /**
     * @brief 处理 QWebSocket 的 stateChanged(QAbstractSocket::SocketState state) 信号
     * @param state 新的连接状态
     */
    void onStateChanged(QAbstractSocket::SocketState state);


private:
    QWebSocket m_webSocket; // 内部持有的 QWebSocket 实例
    QUrl m_url;             // 保存尝试连接的 URL
};

#endif // CWEBSOCKET_H
